﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ClickerClimber.Managers;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using ClickerClimber.Models;
using ClickerClimber.Model;

namespace ClickerClimber.Scenes
{
    public class GameScene : IGameObject, IGameObjectDrawable
    {
        private Board _board;
        private List<Beaver> _beaver;
        private List<Beaver> _beaverTree;
        Beaver _Owl;

        private Texture2D _footerTexture;
        private Texture2D _headerTexture;

        private Texture2D _waterTexture1;
        private Texture2D _waterTexture2;

        private Vector2 _water1Position;
        private Vector2 _water2Position;

        private int _water1Direction;
        private int _water2Direction;

        private float _waterLevel;
        private float _waterTime;

        private Vector2 _tree1Position;
        private Vector2 _tree2Position;
        private Vector2 _tree3Position;

        private Texture2D _treeTexture1;
        private Texture2D _treeTexture2;
        private Texture2D _treeTexture3;

        private Color _nightColor;
        float _timer;
        int _nbClicks;
        int _gameTurnsPlayed;
        private Jimbo _jimbo;

        private int _lastTopHight;

        private Texture2D _winTexture1;
        private Texture2D _winTexture2;
        private Texture2D _loseTexture1;
        private Texture2D _loseTexture2;

        private Texture2D _gameOver;
        private Texture2D _gameWin;

        private bool _drawWin;
        private bool _drawLose;
        private float _winLoseTimer;

        private enum WinLoseState
        {
            IDLE,
            WINLOSE_FIRST_FRAME,
            WINLOSE_SECOND_FRAME
        }

        private WinLoseState _winLoseState;

        private Texture2D _curtain;
        private Rectangle _curtainRectangle;
        private Color _curtainColor;

        public void LoadTextures(Microsoft.Xna.Framework.Content.ContentManager content)
        {
            _footerTexture = content.Load<Texture2D>(GameParameters.FOOTER_TEXTURE_NAME);
            _headerTexture = content.Load<Texture2D>(GameParameters.HEADER_TEXTURE_NAME);

            _waterTexture1 = content.Load<Texture2D>(GameParameters.WATER_1_TEXTURE_NAME);
            _waterTexture2 = content.Load<Texture2D>(GameParameters.WATER_2_TEXTURE_NAME);

            _treeTexture1 = content.Load<Texture2D>(GameParameters.TREE_1_TEXTURE_NAME);
            _treeTexture2 = content.Load<Texture2D>(GameParameters.TREE_2_TEXTURE_NAME);
            _treeTexture3 = content.Load<Texture2D>(GameParameters.TREE_3_TEXTURE_NAME);

            _winTexture1 = content.Load<Texture2D>(GameParameters.WIN_1_TEXTURE_NAME);
            _winTexture2 = content.Load<Texture2D>(GameParameters.WIN_2_TEXTURE_NAME);

            _loseTexture1 = content.Load<Texture2D>(GameParameters.LOSE_1_TEXTURE_NAME);
            _loseTexture2 = content.Load<Texture2D>(GameParameters.LOSE_2_TEXTURE_NAME);

            _gameOver = content.Load<Texture2D>(GameParameters.GAME_OVER_TEXTURE_NAME);
            _gameWin = content.Load<Texture2D>(GameParameters.GAME_WIN_TEXTURE_NAME);

            _board.LoadTextures(content);
            _jimbo.LoadTextures(content);
        }

        public void Draw(SpriteBatch batch)
        {
            Color backgroundColor = new Color(255, 247, 210);
            backgroundColor.R += _nightColor.R;
            backgroundColor.G += _nightColor.G;
            backgroundColor.B += _nightColor.B;

            RendererManager.Instance.Device.Clear(backgroundColor);

            Vector2 footerPosition = new Vector2(0.0f, batch.GraphicsDevice.Viewport.Height-_footerTexture.Height);
            batch.Draw(_footerTexture, GameParameters.SCROLL_OFFSET+footerPosition, Color.White);

            Rectangle headerRectangle = new Rectangle(0, 0, GameParameters.GAME_WIDTH, (int)(_headerTexture.Height*GameParameters.GAME_WIDTH/_headerTexture.Width));
            batch.Draw(_headerTexture, headerRectangle, Color.White);

            _board.Draw(batch);

           
            int x = (int)(GameParameters.SCROLL_OFFSET.X + _tree1Position.X);
            int y = (int)(GameParameters.SCROLL_OFFSET.Y + _tree1Position.Y);
            for (int i = 0; i < 30; i++)
            {
                Rectangle treeRectangle3 = new Rectangle(x, y, _treeTexture3.Width, _treeTexture3.Height);
                y -= _treeTexture3.Height;
                Rectangle treeRectangle1 = new Rectangle(x, y, _treeTexture1.Width, _treeTexture1.Height);
                y -= _treeTexture1.Height;
                Rectangle treeRectangle2 = new Rectangle(x, y, _treeTexture2.Width, _treeTexture2.Height);
                y -= _treeTexture2.Height;

                batch.Draw(_treeTexture1, treeRectangle1, Color.White);
                batch.Draw(_treeTexture2, treeRectangle2, Color.White);
                batch.Draw(_treeTexture3, treeRectangle3, Color.White);
            }

            x = (int)(GameParameters.SCROLL_OFFSET.X + _tree2Position.X);
            y = (int)(GameParameters.SCROLL_OFFSET.Y + _tree2Position.Y);
            for (int i = 0; i < 30; i++)
            {
                Rectangle treeRectangle1 = new Rectangle(x, y, _treeTexture1.Width, _treeTexture1.Height);
                y -= _treeTexture1.Height;
                Rectangle treeRectangle3 = new Rectangle(x, y, _treeTexture3.Width, _treeTexture3.Height);
                y -= _treeTexture3.Height;
                Rectangle treeRectangle2 = new Rectangle(x, y, _treeTexture2.Width, _treeTexture2.Height);
                y -= _treeTexture2.Height;
                

                batch.Draw(_treeTexture1, treeRectangle1, Color.White);
                batch.Draw(_treeTexture2, treeRectangle2, Color.White);
                batch.Draw(_treeTexture3, treeRectangle3, Color.White);
            }

            if (!_drawWin && !_drawLose)
            {
                _jimbo.Draw(batch);
            }

            foreach (Beaver beaver in _beaver)
            {
                beaver.Draw(batch);
            }

            x = (int)(_water1Position.X);
            y = (int)(_waterLevel + _water1Position.Y + GameParameters.SCROLL_OFFSET.Y);
            for (int i = 0; i < _beaverTree.Count; i++)
            {
                _beaverTree[i].Draw(batch);
            }

            _Owl.Draw(batch);

            AnimationManager.Instance.Draw(batch);

            Rectangle waterRectangle = new Rectangle(x, y, _waterTexture1.Width / 2, _waterTexture1.Height / 2);
            batch.Draw(_waterTexture1, waterRectangle, Color.White);

            //waterRectangle = new Rectangle((int)(GameParameters.SCROLL_OFFSET.X + _water2Position.X), (int)(GameParameters.SCROLL_OFFSET.Y + _water2Position.Y), _waterTexture2.Width / 2, _waterTexture2.Height / 2);
            // batch.Draw(_waterTexture2, waterRectangle, Color.White);

            if (_curtain == null)
            {
                //_curtain = new Texture2D(batch.GraphicsDevice, batch.GraphicsDevice.Viewport.Width, batch.GraphicsDevice.Viewport.Height);
                _curtain = new Texture2D(batch.GraphicsDevice, 1, 1);
                _curtain.SetData(new Color[] { Color.Black });
                _curtainRectangle = new Rectangle(0, 0, batch.GraphicsDevice.Viewport.Width, batch.GraphicsDevice.Viewport.Height);
                _curtainColor = new Color(0, 0, 0, 128);
            }

            if (_drawWin)
            {
                this.DrawWin(batch);
            }

            if (_drawLose)
            {
                this.DrawLose(batch);
            }

            float waterPositionY = _waterLevel + _water1Position.Y + GameParameters.SCROLL_OFFSET.Y + 50;
           // batch.Draw(_curtain, new Rectangle(0, (int)waterPositionY, batch.GraphicsDevice.Viewport.Width, 1), Color.Red);

        }

        private void DrawWin(SpriteBatch batch)
        {
            Vector2 position;
            
            switch (_winLoseState)
            {
                case WinLoseState.WINLOSE_FIRST_FRAME:
                    position = new Vector2(batch.GraphicsDevice.Viewport.Width / 2 - _gameWin.Width / 2, batch.GraphicsDevice.Viewport.Height / 2 - _gameWin.Height / 2);
                    batch.Draw(_gameWin, position, Color.White);

                    position = new Vector2(batch.GraphicsDevice.Viewport.Width/2-_winTexture1.Width/2, batch.GraphicsDevice.Viewport.Height/2-_winTexture1.Height/2+100);
                    //batch.Draw(_curtain, _curtainRectangle, _curtainColor);
                    batch.Draw(_winTexture1, position, Color.White);

                    

                    break;
                case WinLoseState.WINLOSE_SECOND_FRAME:
                    position = new Vector2(batch.GraphicsDevice.Viewport.Width / 2 - _gameWin.Width / 2, batch.GraphicsDevice.Viewport.Height / 2 - _gameWin.Height / 2);
                    batch.Draw(_gameWin, position, Color.White);

                    position = new Vector2(batch.GraphicsDevice.Viewport.Width/2 - _winTexture2.Width / 2, batch.GraphicsDevice.Viewport.Height/2 - _winTexture2.Height / 2+100);
                    //batch.Draw(_curtain, _curtainRectangle, _curtainColor);
                    batch.Draw(_winTexture2, position, Color.White);
                    
                    break;
            }
        }

        private void DrawLose(SpriteBatch batch)
        {
            Vector2 position;

            switch (_winLoseState)
            {
                case WinLoseState.WINLOSE_FIRST_FRAME:
                    position = new Vector2(batch.GraphicsDevice.Viewport.Width/2-_gameOver.Width/2, batch.GraphicsDevice.Viewport.Height/2-_gameOver.Height/2);
                    batch.Draw(_gameOver, position, Color.White);

                    position = new Vector2(batch.GraphicsDevice.Viewport.Width/2 - _loseTexture1.Width / 2, batch.GraphicsDevice.Viewport.Height/2 - _loseTexture1.Height / 2+100);
                    //batch.Draw(_curtain, _curtainRectangle, _curtainColor);
                    batch.Draw(_loseTexture1, position, Color.White);

                    
                    break;
                case WinLoseState.WINLOSE_SECOND_FRAME:
                    position = new Vector2(batch.GraphicsDevice.Viewport.Width/2-_gameOver.Width/2, batch.GraphicsDevice.Viewport.Height/2-_gameOver.Height/2);
                    batch.Draw(_gameOver, position, Color.White);

                    position = new Vector2(batch.GraphicsDevice.Viewport.Width/2 - _loseTexture2.Width / 2, batch.GraphicsDevice.Viewport.Height/2 - _loseTexture2.Height / 2+100);
                    //batch.Draw(_curtain, _curtainRectangle, _curtainColor);
                    batch.Draw(_loseTexture2, position, Color.White);

                    
                    break;
            }
        }

        public void OnClick()
        {
            foreach (Beaver beaver in _beaver)
            {
                beaver.OnClick();
            }
            _nbClicks++;
            _gameTurnsPlayed++;
        }

        public void Initialize()
        {
            _board = new Board();
            _board.Initialize();
            _nightColor = new Color(0, 0, 0);
            _water1Position = new Vector2(-50.0f, GameParameters.INITIAL_LEVEL_WATER_Y);
            _water1Direction = 1;
            _water2Position = new Vector2(0.0f, 395.0f);
            _water2Direction = -1;
            _waterLevel = 0;
            _waterTime = GameParameters.MIN_WATER_TIME;
            _tree1Position = new Vector2(25.0f, 500.0f);
            _tree2Position = new Vector2(625.0f,500.0f);
            _tree3Position = new Vector2(50.0f, 150.0f);
            _timer = 0.0f;
            _nbClicks = 0;
            _gameTurnsPlayed = 0;
            _beaver = new List<Beaver>();
            _beaverTree = new List<Beaver>();
            _jimbo = new Jimbo();
            _jimbo.Initialize();
            _lastTopHight = 0;
            _drawLose = false;
            _drawWin = false;
            _winLoseTimer = 1.0f;
            _winLoseState = WinLoseState.IDLE;
            _Owl = new Beaver();

                _Owl.LoadTextures(RendererManager.Instance.Content);
               {
                    //beaverTree.ItemPosition = _tree1Position;
                   /* _Owl.Position = _tree1Position;
                    Vector2 offset = new Vector2(100, -GameParameters.SCROLL_OFFSET.Y + 100);
                    _Owl.Position += offset;*/
                   _Owl.Position = GameParameters.OWL_POSITION;
                    _Owl.SetState(Beaver.eState.eOwl);
                }
        }

        public void Update(GameTime gameTime)
        {
            UpdateEndGame(gameTime);

            _board.Update(gameTime, _beaver);
            UpdateScroll(gameTime);
            UpdateBeaver(gameTime);

            UpdateWater(gameTime);
            UpdateJimbo(gameTime);
            UpdateOwl(gameTime);
            _lastTopHight = DataManager.Instance.HUDScene.Hight;
            DataManager.Instance.HUDScene.Hight = _board.TopPosition;
        }

        public void OnClick(Vector2 pos)
        {
            if (_board != null)
            {
                _board.OnClick(pos, _beaver);
                RemoveBeavers();
            }
        }


        #region Support methods

        private void RemoveBeavers()
        {
            // remove from pattern
            List<Pair> pattern = _board.PatternCells;
            if (pattern != null && pattern.Count > 2)
            {
                for (int i = 0; i < _beaver.Count; i++)
                {
                    foreach (Pair pair in pattern)
                    {                    
                        if ((((Math.Abs(pair.Row - _beaver[i].ItemPosition.Row) == 1) && (pair.Column == _beaver[i].ItemPosition.Column)) ||
                            ((Math.Abs(pair.Column - _beaver[i].ItemPosition.Column) == 1) && (pair.Row == _beaver[i].ItemPosition.Row))) &&
                            _beaver[i].State!= Beaver.eState.eFly)
                        {
                            _beaver[i].SetState(Beaver.eState.eDie);
                            _board.GetItem(_beaver[i].ItemPosition.Column, _beaver[i].ItemPosition.Row).IsVisible = true;
                            //_beaver.RemoveAt(i);
                        }
                    }
                    //die because of water
                    if(IsBeavenDrown(_beaver[i])) 
                    {
                        _beaver[i].SetState(Beaver.eState.eDie);
                        _board.GetItem(_beaver[i].ItemPosition.Column, _beaver[i].ItemPosition.Row).IsVisible = true;
                    }
                }
                
            }
        }

        private void UpdateOwl(GameTime gameTime)
        {
            float owlPositionY = _Owl.Position.Y;
            float waterPositionY = _waterLevel + _water1Position.Y + GameParameters.SCROLL_OFFSET.Y+50;
            if (waterPositionY <= owlPositionY )
            {
                _Owl.SetState(Beaver.eState.eDrown);
            }
            else
            {
                _Owl.SetState(Beaver.eState.eOwl);
            }
        }

        private void UpdateEndGame(GameTime gameTime)
        {
            bool jimboDrown = false;
            bool timeout = DataManager.Instance.HUDScene.Timeout;
            float jimboPositionY = _jimbo.Position.Y + GameParameters.SCROLL_OFFSET.Y-_jimbo.Height;
            float waterPositionY = _waterLevel + _water1Position.Y + GameParameters.SCROLL_OFFSET.Y + 50;
            if (waterPositionY <= jimboPositionY + 2*_jimbo.Height / 3 || (_waterLevel + _water1Position.Y + GameParameters.SCROLL_OFFSET.Y -2< GameParameters.GAME_HEIGHT - _waterTexture1.Height / 2)) 
            {
                jimboDrown = true;
            }

            if(timeout && !jimboDrown)
            {
                this.GameWin(gameTime);
            }
            else if(jimboDrown)
            {
                this.GameLose(gameTime);
            }
        }

        private void GameWin(GameTime gameTime)
        {
            _drawWin = true;
            switch (_winLoseState)
            {
                case WinLoseState.IDLE:
                    _winLoseTimer = 0.5f;
                    _winLoseState = WinLoseState.WINLOSE_FIRST_FRAME;
                    AudioManager.Instance.StopMusic();
                    AudioManager.Instance.PlaySound(AudioManager.eSound.gameWin);
                    break;
                case WinLoseState.WINLOSE_FIRST_FRAME:
                    _winLoseTimer -= gameTime.ElapsedGameTime.Milliseconds / 1000.0f;
                    if (_winLoseTimer <= 0.0f)
                    {
                        _winLoseTimer = 3.0f;
                        _winLoseState = WinLoseState.WINLOSE_SECOND_FRAME;
                    }
                    break;
                case WinLoseState.WINLOSE_SECOND_FRAME:
                    _winLoseTimer -= gameTime.ElapsedGameTime.Milliseconds / 1000.0f;
                    if (_winLoseTimer <= 0.0f)
                    {
                        RendererManager.Instance.LoadScene(DataManager.Instance.SplashScreenScene);
                        GameController.Instance.GameState = GameController.eGameState.eGameState_PreInit;
                        GameController.Instance.StartUp();
                        AnimationManager.Instance.Reset();
                    }
                    break;
            }
        }

        private void GameLose(GameTime gameTime)
        {
            _drawLose = true;
            switch (_winLoseState)
            {
                case WinLoseState.IDLE:
                    _winLoseTimer = 0.5f;
                    _winLoseState = WinLoseState.WINLOSE_FIRST_FRAME;
                    AudioManager.Instance.StopMusic();
                    AudioManager.Instance.PlaySound(AudioManager.eSound.gameOver);
                    break;
                case WinLoseState.WINLOSE_FIRST_FRAME:
                    _winLoseTimer -= gameTime.ElapsedGameTime.Milliseconds / 1000.0f;
                    if (_winLoseTimer <= 0.0f)
                    {
                        _winLoseTimer = 3.0f;
                        _winLoseState = WinLoseState.WINLOSE_SECOND_FRAME;
                    }
                    break;
                case WinLoseState.WINLOSE_SECOND_FRAME:
                    _winLoseTimer -= gameTime.ElapsedGameTime.Milliseconds / 1000.0f;
                    if (_winLoseTimer <= 0.0f)
                    {
                        RendererManager.Instance.LoadScene(DataManager.Instance.SplashScreenScene);
                        GameController.Instance.GameState = GameController.eGameState.eGameState_PreInit;
                        GameController.Instance.StartUp();
                        AnimationManager.Instance.Reset();
                    }
                    break;
            }
        }

        private void UpdateBeaver(GameTime gameTime)
        {
            const float cfTime = 2.0f;
            //if (_timer > cfTime)
            if (_nbClicks%8 == 3)
            {
                CreateBeaverOnBoard(gameTime);
                _nbClicks = 0;
                _timer -= cfTime;

                AddBeaverOnTree(gameTime);                
            }
            //update board for the current beavers
            
            //looking for beavers that destroy a board background each two turns.
            List<Pair> positions = _board.GetNewBeaverPositions();
            int index = 0;
            bool found = false;

            for(int i=0; i< _beaver.Count; i++)
            {
                if (_beaver[i].State == Beaver.eState.eBite)
                {
                    _board.GetItem(_beaver[i].ItemPosition.Column, _beaver[i].ItemPosition.Row).IsVisible = false;
                }
                _beaver[i].Update(gameTime);
                if (_beaver[i].NbClicks == 0)
                {
                    _board.AddItemToDelete(_beaver[i].ItemPosition);
                    _board.GetItem(_beaver[i].ItemPosition.Column, _beaver[i].ItemPosition.Row).IsVisible = true;
                    //_beaver[i].State = Beaver.eState.eDisabled;

                    //new beaver position
                    _beaver[i].NbClicks = 2;
                    Vector2 beaverPosition = _beaver[i].Position;

                    while (index < positions.Count && !found && _beaver[i].IsAlive)
                    {
                        Pair pos = positions[index];

                        _beaver[i].ItemPosition = pos;
                        _beaver[i].Position = _board.GetPosition(pos.Column, pos.Row);
                        if (!IsBeavenDrown(_beaver[i]) )//&& IsBeaverFreePosition(pos))
                        {
                            //get a beaver from tree
                            //_board.GetItem(pos.Column, pos.Row).IsVisible = false;
                            _beaver[i].FlyFromTo(beaverPosition, _board.GetPosition(pos.Column, pos.Row));                            
                            found = true;
                        }
                        ++index;
                    }

                    if (!found)
                    {
                        _beaver[i].SetState(Beaver.eState.eDisabled);
                        //_board.DeleteBackgrounds(1);
                        _beaver.RemoveAt(i);
                    }
                }
            }

            //Update beavers on trees
            for (int i = 0; i < _beaverTree.Count; i++)
            {
                _beaverTree[i].Update(gameTime);
            }

            _Owl.Update(gameTime);

            _timer += gameTime.ElapsedGameTime.Milliseconds / 1000.0f;
        }

        private bool IsBeavenDrown(Beaver beaver)
        {
            float beaverPositionY = beaver.Position.Y + GameParameters.SCROLL_OFFSET.Y+20;
            float waterPositionY = _waterLevel + _water1Position.Y + GameParameters.SCROLL_OFFSET.Y+ 50;
            if (waterPositionY <= beaverPositionY)
            {
                return true;
            }
            return false;
        }

        private void CreateBeaverOnBoard(GameTime gameTime)
        {
            List<Pair> positions = _board.GetNewBeaverPositions();
            int index = 0;
            bool found = false;
            Beaver beaverOnTree = GetBeaverOnTree();

            if(beaverOnTree== null) return;

            Beaver beaver = new Beaver();
            beaver.LoadTextures(RendererManager.Instance.Content);
            beaver.NbClicks = 2;
            beaver.Initialize();

            while (index < positions.Count && !found)
            {
                Pair pos = positions[index];

                beaver.ItemPosition = pos;
                beaver.Position = _board.GetPosition(pos.Column, pos.Row);
                if (!IsBeavenDrown(beaver) && IsBeaverFreePosition(pos))
                {
                    //get a beaver from tree
                    //_board.GetItem(pos.Column, pos.Row).IsVisible = false;
                    beaver.FlyFromTo(beaverOnTree.Position, _board.GetPosition(pos.Column, pos.Row));
                    _beaverTree.Remove(beaverOnTree);
                    _beaver.Add(beaver);
                    found = true;
                }
                ++index;
            }
        }

        private bool IsBeaverFreePosition(Pair pos)
        {
            foreach (Beaver beaver in _beaver)
            {
                if (beaver.ItemPosition.Column == pos.Column && beaver.ItemPosition.Row == pos.Row)
                {
                    return false;
                }
            }
            return true;
        }

        private Beaver GetBeaverOnTree()
        {
            if (_beaverTree.Count > 0)
            {
                return _beaverTree[0];
            }

            return null;
        }

        private void AddBeaverOnTree(GameTime gameTime)
        {
            int iRand = (int)gameTime.TotalGameTime.Milliseconds;
            Beaver beaverTree = new Beaver();
            beaverTree.LoadTextures(RendererManager.Instance.Content);
            if ((iRand % 2) == 1)
            {
                //beaverTree.ItemPosition = _tree1Position;
                beaverTree.Position = _tree1Position;
                Vector2 offset = new Vector2(100, -GameParameters.SCROLL_OFFSET.Y + 100);
                beaverTree.Position += offset;
                beaverTree.SetState(Beaver.eState.eUp);
            }
            else
            {
                beaverTree.Position = _tree2Position;
                Vector2 offset = new Vector2(100, -GameParameters.SCROLL_OFFSET.Y + 100);
                beaverTree.Position += offset;
                beaverTree.SetState(Beaver.eState.eUp);
            }
            _beaverTree.Add(beaverTree);
        }

        private void UpdateWater(GameTime gameTime)
        {
            float vel1 = (float)( gameTime.ElapsedGameTime.Milliseconds * 0.015);
            float vel2 = (float)(gameTime.ElapsedGameTime.Milliseconds * 0.01);


            /*if (_lastTopHight != DataManager.Instance.HUDScene.Hight)
            {
                _waterTime = Math.Min(GameParameters.MAX_WATER_TIME, _waterTime + DataManager.Instance.HUDScene.Hight - _lastTopHight);
            }

            float waterIncrement = _waterTime / 1000.0f * gameTime.ElapsedGameTime.Milliseconds;*/

            float waterIncrement = _board.Rules.WaterRaise(_gameTurnsPlayed, (int)DataManager.Instance.HUDScene.Time);
            
            if (_waterLevel - waterIncrement + _water1Position.Y + GameParameters.SCROLL_OFFSET.Y < GameParameters.GAME_HEIGHT - _waterTexture1.Height / 2)
            {
             
            }
            else
            {
                _waterLevel -= waterIncrement;
            }


            if (_water1Position.Y > GameParameters.INITIAL_LEVEL_WATER_Y + _waterLevel/* && _water1Position.Y + _waterTexture1.Height / 2 > GameParameters.GAME_HEIGHT*/)
            {
                _water1Position = Vector2.Lerp(_water1Position, new Vector2(0, - GameParameters.INITIAL_LEVEL_WATER_Y + _waterLevel), 0.001f);
            }

            

            if (_water1Direction > 0)
            {
                if (_water1Position.X + _water1Direction < 0.0f)
                {
                    _water1Position.X += _water1Direction * vel1;
                }
                else
                {
                    _water1Direction = -_water1Direction;
                }
            }

            if (_water1Direction < 0)
            {
                if (_water1Position.X + _water1Direction > -50.0f)
                {
                    _water1Position.X += _water1Direction * vel1;
                }
                else
                {
                    _water1Direction = -_water1Direction;
                }
            }
            
            if (_water2Direction > 0)
            {
                if (_water2Position.X + _water2Direction < 0.0f)
                {
                    _water2Position.X += _water2Direction * vel2;
                }
                else
                {
                    _water2Direction = -_water2Direction;
                }
            }

            if (_water2Direction < 0)
            {
                if (_water2Position.X + _water2Direction > -50.0f)
                {
                    _water2Position.X += _water2Direction * vel2;
                }
                else
                {
                    _water2Direction = -_water2Direction;
                }
            }
        }

        private void UpdateJimbo(GameTime gameTime)
        {
            Vector2 topBoardPosition = _board.GetTopBackgroundPosition();
            topBoardPosition.Y -= GameParameters.BOARD_CELL_HEIGHT / 2;
            _jimbo.Position = topBoardPosition;

            _jimbo.Update(gameTime);
        }

        private void UpdateScroll(GameTime gameTime)
        {
            Vector2 topBoardPosition = _board.GetTopBackgroundPosition();
            
            if (topBoardPosition.Y+GameParameters.SCROLL_OFFSET.Y < GameParameters.MARGIN_TOP)
            {
                float value = GameParameters.MARGIN_TOP - topBoardPosition.Y;
                if (value > 0)
                {
                    GameParameters.SCROLL_OFFSET = Vector2.Lerp(GameParameters.SCROLL_OFFSET, new Vector2(0, value), 0.1f);
                }
                /*_nightColor.R -= (byte)1;
                _nightColor.G -= (byte)1;
                _nightColor.B -= (byte)1;*/
            }

            if (topBoardPosition.Y + GameParameters.SCROLL_OFFSET.Y > GameParameters.MARGIN_BOTTOM && GameParameters.SCROLL_OFFSET.Y > 0)
            {
                GameParameters.SCROLL_OFFSET = Vector2.Lerp(GameParameters.SCROLL_OFFSET, new Vector2(0, GameParameters.MARGIN_BOTTOM - topBoardPosition.Y), 0.1f);
            }
        }

        #endregion

        #region Properties

        public Board Board
        {
            get
            {
                return _board;
            }
        }

        #endregion Properties
    }
}
